<?php
namespace App\Common\Model\Base\DataManager;

use App\Common as com;
use App\Common\Model\Base as nameModelBase;

/**
 * Class DataManager
 * @property $dataStore
 * @method \Hyperf\Database\Model\Builder goModelQuery()
 * @method com\Model\Base\DataUnit\DataOperateS goDatas()
 */
trait MainV2 {

	use com\Cla\ClaBase\Traits\GoPool;

	private $isInjectParent = false;

	protected $mainDataId = null;


	/**
	 * 是否为创建数据模式
	 * @return bool
	 */
	public function isCreate(  ):bool {
		return empty( $this->goModelQuery()->getQuery()->wheres );
	}

	/**
	 * 注入Parent对象
	 * @param $parentObj
	 * @return MainV2
	 */
	public function injectParent( $parentObj ):self {
		$this->isInjectParent = true;
		$this->goPoolSet( 'goParent', $parentObj );
		//
		return $this;
	}

	/**
	 * 是否有注入Parent对象
	 * @return bool
	 */
	protected function isInjectParent(  ):bool {
		return $this->isInjectParent;
	}

	public function saveReMainId(  ):int {
		return $this->saveReThis()->getMainDataId();
	}

	/**
	 * 保存数据
	 * @return $this 返回数据id
	 * @throws
	 */
	public function saveReThis(  ):self {
		\Hyperf\DbConnection\Db::beginTransaction();
		try {
			if( method_exists( $this, '_save' ) ){
				$dataId = $this->_save();
			}else{
				if( $this->methodExists_GoParent() ){
					$mainDataId = $this->goParent()->saveAllReMainId();
				}
				// 创建->主表数据
				$dataId = $this->saveOfSelf( $mainDataId ?? null );
				//
				if( method_exists( $this, '_saveOfSub' ) ){
					// 创建部分
					$this->_saveOfSub( $dataId );
				}
			}
			//
			\Hyperf\DbConnection\Db::commit();
			//
			$this->setMainDataId( $mainDataId ?? $dataId );
			$this->setDataId( $dataId );
		}catch( \Exception $e ){
			\Hyperf\DbConnection\Db::rollBack();
			return com\Lib\Err\Exception\Try_::dealWithException( $e, true );
		}finally{
			// 重置数据
			$this->goDataS()->reset();
		}
		//
		return $this;
	}

	private function setMainDataId( int $mainDataId ):self {
		$this->mainDataId = $mainDataId;
		return $this;
	}

	private function getMainDataId(  ):int {
		return $this->mainDataId;
	}


	/**
	 * 保存数据(返回数据id)
	 * @return int 返回数据id
	 * @throws
	 */
	public function saveReId(  ):int {
		return $this->saveReThis()->getDataIdOrFail();
	}

	//	abstract protected function _saveOfSub( int $dataId );

	/**
	 * 保存自身
	 * @return int
	 */
	protected function saveOfSelf( int $mainDataId = null ):int {
		if( $this->isCreate() ){
			// 创建
			if( $mainDataId !== null ){
				$saveData = [
					$this->mainDataFieldName => $mainDataId,
				];
			}
			//
			$saveRes = $this->saveOfCreate( $saveData ?? [], false );
			//
			return $saveRes->getDataIdOrFail();
		}else{
			// 更新
			if( $mainDataId !== null ){
				$this->goModelQuery()->where( $this->mainDataFieldName, $mainDataId );
			}
			//
			$this->saveOfUpdate( [], false );
			//
			return $this->getDataIdOrFail();
		}
	}

	/**
	 * 检查是否可删除
	 * @return void
	 * @throws
	 */
	private function checkIsDeleteOrFail(  ):void {
		if( $this->isCreate() ){
			throw com\Lib\Err\Exception::makeOfNew( 'Create 模式不可删除', com\Lib\Err\Code::$undefined );
		}
	}

	/**
	 * 删除全部关联数据
	 * @return bool [true][必返]
	 * @throws
	 */
	public function deleteTree(  ):bool {
		$this->checkIsDeleteOrFail();
		//
		\Hyperf\DbConnection\Db::beginTransaction();
		try {
			//
			if( method_exists( $this, '_deleteTree' ) ){
				$this->_deleteTree();
			}else{
				$this->deleteTreeOfDown( true );
				$this->deleteTreeOfParent();
			}
			//
			\Hyperf\DbConnection\Db::commit();
			return true;
		}catch( \Exception $e ){
			\Hyperf\DbConnection\Db::rollBack();
			return com\Lib\Err\Exception\Try_::dealWithException( $e, true );
		}
	}

	/**
	 * 是否存在GoParent方法
	 * @return bool
	 */
	private function methodExists_GoParent(  ):bool {
		return method_exists( $this, 'goParent' );
	}
	
	/**
	 * 删除上级级关联数据
	 * @param  bool $isDelCurrentTable 是否删除当前表 [false][默认]
	 * @return bool [true][必返]
	 * @throws
	 */
	public function deleteTreeOfParent( bool $isDelCurrentTable = false ):bool {
		$this->checkIsDeleteOrFail();
		//
		\Hyperf\DbConnection\Db::beginTransaction();
		try {
			//
			if( $this->methodExists_GoParent() ){
				$this->goParent()->deleteTreeOfParent( true );
				if( $isDelCurrentTable === true ){
					$this->delete();
				}
			}
			//
			\Hyperf\DbConnection\Db::commit();
			return true;
		}catch( \Exception $e ){
			\Hyperf\DbConnection\Db::rollBack();
			return com\Lib\Err\Exception\Try_::dealWithException( $e, true );
		}
	}

	/**
	 * 删除下级关联数据
	 * @param  bool $isDelCurrentTable 是否删除当前表 [false][默认]
	 * @return bool [true][必返]
	 * @throws
	 */
	public function deleteTreeOfDown( bool $isDelCurrentTable = false ):bool  {
		$this->checkIsDeleteOrFail();
		//
		\Hyperf\DbConnection\Db::beginTransaction();
		try {
			//
			if( method_exists( $this, '_deleteTreeOfDown' ) ){
				$this->_deleteTreeOfDown( true );
			}
			//
			if( $isDelCurrentTable === true ){
				$this->delete();
			}
			//
			\Hyperf\DbConnection\Db::commit();
			return true;
		}catch( \Exception $e ){
			\Hyperf\DbConnection\Db::rollBack();
			return com\Lib\Err\Exception\Try_::dealWithException( $e, true );
		}
	}

}
